#include<iostream>
#include <sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<netdb.h>
#include<arpa/inet.h>
#include"rio.h"
#include<unistd.h>
#include<stdlib.h>

using namespace std;

int open_clientfd(char*c_hostname,char* port){
    int clientfd;
    struct addrinfo *p,*listp,hints;
    memset(&hints,0,sizeof(struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_NUMERICSERV;
    hints.ai_flags |= AI_ADDRCONFIG;
    if(getaddrinfo(c_hostname,port,&hints,&listp)!=0){
        cout<<"getadd fail!"<<endl;
    }
        for(p = listp;p;p = p->ai_next){
        if((clientfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol))<0){
        cout<<"socked fail!"<<endl;
        continue;
        }
        cout<<clientfd<<endl;
        if(connect(clientfd,p->ai_addr,p->ai_addrlen)!=-1){
            cout<<"connect sucessfully!"<<endl;
            break;
        }
        close(clientfd);
    }
    freeaddrinfo(listp);
    if(!p){
        cout<<"connect fail!"<<endl;
        exit(0);
    }
    else{
        return clientfd;
    }
}
int open_listenfd(char* port){
    int fd ;
    int optval = 1;
    struct addrinfo *p,*listp,hints;
    memset(&hints,0,sizeof(struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE|AI_ADDRCONFIG;
    hints.ai_flags |= AI_NUMERICSERV;
    if(getaddrinfo(NULL,port,&hints,&listp)!=0){
        cout<<"getadd fail!"<<endl;
    }
    for(p = listp;p;p = p->ai_next){
        if((fd = socket(p->ai_family,p->ai_socktype,p->ai_protocol))<0){
        cout<<"socked fail!"<<endl;
        continue;
        }
        cout<<fd<<endl;
        setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const void*)&optval,sizeof(int));
        if(bind(fd,p->ai_addr,p->ai_addrlen)==0){
        cout<<"bind succeed!!"<<endl;
        break;
        }
        cout<<"bind fail!"<<endl;
        close(fd);
    }
    freeaddrinfo(listp);
    if(!p){
        cout<<"fail!"<<endl;
        exit(0);
    }
    if(listen(fd,1024)<0){
        cout<<"listen fail!"<<endl;
    }
    return fd;
}
void echo(int fd){
        rio_t rio;
        size_t n;
        char buf[1000];
        rio_readinitb(&rio,fd);
        while((n = rio_readlineb(&rio,buf,1000))!=0){
            //fputs(buf,stdout);
            cout<<n<<endl;
            rio_writen(fd,buf,n);
        }
}

